﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Serialization.Formatters.Binary;
/*---------------------------*/
using Emgu.CV;

//using Emgu.CV.GPU;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using DualChannel_v2._0;
using System.Reflection;
using System.Drawing.Drawing2D;


namespace DualChannelProject
{
    public partial class MatcherForm : Form
    {
        public Image<Bgr, byte> BWimage = new Image<Bgr, byte>(100, 100);
        public Image<Bgr, byte> Cimage = new Image<Bgr, byte>(100, 100);
        public Matrix<float> AffineMatrix = new Matrix<float>(2, 3);
        public Matrix<float> AffineMatrixInverse = new Matrix<float>(2, 3);
        PointF[] src = new PointF[3];
        PointF[] dst = new PointF[3];
        float ZoomValue = 0, ZoomSensitivity = (float)1 / 1000, ShearSensitivity = (float)1 / 1000, RotSensitivity = (float)1 / 100, ScallingSensitivity = (float)1 / 1000;
        float ShearXValue = 0, ShearYValue = 0, ScallingXValue = 0, ScallingYValue = 0;

        bool AutoAffineMode = false;
        string[] HelpActionTemplate = new[] { "Щелкните на Ч/Б изображении в точке ", "Щелкните на цветном изображении по той же точке "};
        PointF[] AASource = new PointF[3];
        PointF[] AADest = new PointF[3];

        bool drawCropRect = false;
        bool cropResize = false;
        Point baseResizePoint = new Point(0, 0);
        public  Rectangle CropRectangle;
        public float scale = 1;
        private float OldRotAngle,DeltaRotAngle;
        
        public MatcherForm()
        {
            InitializeComponent();

            src[0] = new PointF(0, 0);
            src[1] = new PointF(0, 100);
            src[2] = new PointF(100, 0);
            dst[0] = new PointF(0, 0);
            dst[1] = new PointF(0, 100);
            dst[2] = new PointF(100, 0);
            affmatrixbox.Rows.Add(2);
            affmatrixbox.Rows[0].HeaderCell.Value = "X";
            affmatrixbox.Rows[1].HeaderCell.Value = "Y";

            DoubleBuffered = true;
        }
        
        public void MartixViewUpdate()
        {
            affmatrixbox.Rows[0].SetValues(AffineMatrix[0, 0], AffineMatrix[0, 1], AffineMatrix[0, 2]);
            affmatrixbox.Rows[1].SetValues(AffineMatrix[1, 0], AffineMatrix[1, 1], AffineMatrix[1, 2]);
            AffineMatrixInverse = AffineMatrix.Clone();
            AffineMatrixInverse[0, 2] = -AffineMatrix[0, 2] * AffineMatrix[0, 0] + AffineMatrix[1, 2] * AffineMatrix[0, 1];
            AffineMatrixInverse[1, 2] = -AffineMatrix[1, 2] * AffineMatrix[1, 1] - AffineMatrix[1, 0] * AffineMatrix[0, 2];
        }

        #region EditButtons
        private void buttonZoomIn_Click_1(object sender, EventArgs e)
        {
            ZoomValue += 1 * ZoomSensitivity;
            textBoxZoom.Text = String.Format("{0}", (ZoomValue));
            dst = MatcherUtilities.ZoomImgIn(src, dst, ZoomValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
            // matrixBox.
        }
        private void buttonZoomOut_Click(object sender, EventArgs e)
        {
            ZoomValue -= 1 * ZoomSensitivity;
            textBoxZoom.Text = String.Format("{0}", (ZoomValue));
            dst = MatcherUtilities.ZoomImgOut(src, dst, ZoomValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        private void buttonShearX_Click(object sender, EventArgs e)
        {
            ShearXValue -= 1 * ShearSensitivity;
            textBoxShearX.Text = String.Format("{0}", ShearXValue);
            dst = MatcherUtilities.ShearX(src, dst, ShearXValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        private void buttonShearX2_Click(object sender, EventArgs e)
        {
            ShearXValue += 1 * ShearSensitivity;
            textBoxShearX.Text = String.Format("{0}", ShearXValue);
            dst = MatcherUtilities.ShearX2(src, dst, ShearXValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        private void buttonShearY_Click(object sender, EventArgs e)
        {
            ShearYValue -= 1 * ShearSensitivity;
            textBoxShearY.Text = String.Format("{0}", ShearYValue);
            dst = MatcherUtilities.ShearY(src, dst, ShearYValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        private void buttonShearY2_Click(object sender, EventArgs e)
        {
            ShearYValue += 1 * ShearSensitivity;
            textBoxShearY.Text = String.Format("{0}", ShearYValue);
            dst = MatcherUtilities.ShearY2(src, dst, ShearYValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }

        private void hScrollBarRot_ValueChanged(object sender, EventArgs e)
        {
            textBoxRot.Text = String.Format("{0}", ((hScrollBarRot.Value*RotSensitivity )));
            DeltaRotAngle= hScrollBarRot.Value*RotSensitivity-OldRotAngle;
            OldRotAngle = hScrollBarRot.Value * RotSensitivity;
            PointF center = new PointF((dst[0].X + dst[2].X) / 2, (dst[0].Y + dst[1].Y) / 2);
            
            PointF centerAff = new PointF(
                center.X * AffineMatrix[0, 0] - center.Y * AffineMatrix[0, 1] - AffineMatrix[0, 2] * AffineMatrix[0, 0] + AffineMatrix[1, 2] * AffineMatrix[0,1],
               -center.X * AffineMatrix[1, 0] + center.Y * AffineMatrix[1, 1] - AffineMatrix[1, 2] * AffineMatrix[1, 1] - AffineMatrix[0, 2] * AffineMatrix[0, 1]);

                
            dst = MatcherUtilities.Rotation(src, dst, DeltaRotAngle, center,centerAff);

            //AffineMatrix.Ptr = CvInvoke.cv2DRotationMatrix(center,(double)hScrollBarRot.Value,1, AffineMatrix);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }

        private void buttonUp_Click(object sender, EventArgs e)
        {

            dst = MatcherUtilities.TranslatUp(src, dst, DeltaValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            //if (matrixBox.Matrix != null) matrixBox.Matrix.Dispose(); 
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        private void buttonDown_Click(object sender, EventArgs e)
        {
            //ValueY -= 1;
            dst = MatcherUtilities.TranslatDown(src, dst, DeltaValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        private void buttonRight_Click(object sender, EventArgs e)
        {
            //ValueX += 1;
            dst = MatcherUtilities.TranslatRight(src, dst, DeltaValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        private void buttonLeft_Click(object sender, EventArgs e)
        {
            //ValueX -= 1;
            dst = MatcherUtilities.TranslatLeft(src, dst, DeltaValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }

        private void buttonScaleX_Click(object sender, EventArgs e)
        {
            ScallingXValue += 1 * ScallingSensitivity;
            textBoxScaleX.Text = String.Format("{0}", ScallingXValue);
            dst = MatcherUtilities.ScallingX(src, dst, ScallingXValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        private void buttonScaleX2_Click(object sender, EventArgs e)
        {
            ScallingXValue += 1 * ScallingSensitivity;
            textBoxScaleX.Text = String.Format("{0}", ScallingXValue);
            dst = MatcherUtilities.ScallingX2(src, dst, ScallingXValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        private void buttonScaleY_Click(object sender, EventArgs e)
        {
            ScallingYValue += 1 * ScallingSensitivity;
            textBoxScaleY.Text = String.Format("{0}", ScallingYValue);
            dst = MatcherUtilities.ScallingY2(src, dst, ScallingYValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        private void buttonScaleY2_Click(object sender, EventArgs e)
        {
            ScallingYValue -= 1 * ScallingSensitivity;
            textBoxScaleY.Text = String.Format("{0}", ScallingYValue);
            dst = MatcherUtilities.ScallingY(src, dst, ScallingYValue);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
            //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        
        #endregion
        #region SensivityToolStrip
        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            ZoomSensitivity = 1;
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            ZoomSensitivity = (float)1 / 10;
        }

        private void toolStripMenuItem4_Click(object sender, EventArgs e)
        {
            ZoomSensitivity = (float)1 / 100;
        }

        private void toolStripMenuItem11_Click(object sender, EventArgs e)
        {
            ZoomSensitivity = (float)1 / 1000;
        }

        private void toolStripMenuItem5_Click_1(object sender, EventArgs e)
        {
            ShearSensitivity = 1;
        }

        private void toolStripMenuItem6_Click(object sender, EventArgs e)
        {
            ShearSensitivity = (float)1 / 10;
        }

        private void toolStripMenuItem7_Click(object sender, EventArgs e)
        {
            ShearSensitivity = (float)1 / 100;
        }

        private void toolStripMenuItem8_Click(object sender, EventArgs e)
        {
            ShearSensitivity = (float)1 / 1000;
        }

        private void toolStripMenuItem9_Click(object sender, EventArgs e)
        {
            RotSensitivity = 1;
            hScrollBarRot.Maximum = (int)(360 / RotSensitivity);
            hScrollBarRot.Minimum = (int)(-360 / RotSensitivity);
        }

        private void toolStripMenuItem10_Click(object sender, EventArgs e)
        {
            RotSensitivity = (float)1 / 10;
            hScrollBarRot.Maximum = (int)(360 / RotSensitivity);
            hScrollBarRot.Minimum = (int)(-360 / RotSensitivity);
        }

        private void toolStripMenuItem12_Click(object sender, EventArgs e)
        {
            RotSensitivity = (float)1 / 100;
            hScrollBarRot.Maximum = (int)(360 / RotSensitivity);
            hScrollBarRot.Minimum = (int)(-360 / RotSensitivity);
        }

        private void toolStripMenuItem13_Click(object sender, EventArgs e)
        {
            ScallingSensitivity = 1;
        }

        private void toolStripMenuItem14_Click(object sender, EventArgs e)
        {
            ScallingSensitivity = (float)1 / 10;
        }

        private void toolStripMenuItem15_Click(object sender, EventArgs e)
        {
            ScallingSensitivity = (float)1 / 100;
        }

        private void toolStripMenuItem16_Click(object sender, EventArgs e)
        {
            ScallingSensitivity = (float)1 / 1000;
        } 
        #endregion

        

        int DeltaValue
        { get { return (int)delta.Value; } }

        private void MatcherForm_Load(object sender, EventArgs e)
        {
            
            OldRotAngle = hScrollBarRot.Value*RotSensitivity;
            hScrollBarRot.Maximum = (int)(360 / RotSensitivity);
            hScrollBarRot.Minimum = (int)(-360 / RotSensitivity);
           
            if (Cimage != null && BWimage != null)
            {
                src[0] = new PointF(0, 0);
                src[1] = new PointF(0, Cimage.Height);
                src[2] = new PointF(Cimage.Width, 0);
                dst[0] = new PointF(0, 0);
                dst[1] = new PointF(0, Cimage.Height);
                dst[2] = new PointF(Cimage.Width, 0);
                imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrixInverse)).Bitmap;
                scale = Math.Max((float)Cimage.Width / imageBoxMatcher.Width, (float)Cimage.Height / imageBoxMatcher.Height);

                PointF[] ddd = new PointF[3];
                dst.CopyTo(ddd, 0);
                for (int i = 0; i < 3; i++)
                {
                    dst[i].X = ddd[i].X * AffineMatrix[0, 0] + ddd[i].Y * AffineMatrix[0, 1] + AffineMatrix[0, 2];
                    dst[i].Y = ddd[i].X * AffineMatrix[1, 0] + ddd[i].Y * AffineMatrix[1, 1] + AffineMatrix[1, 2];
                }
                MartixViewUpdate();
                pInfo = imageBoxMatcher.GetType().GetProperty("ImageRectangle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                imrect = (Rectangle)pInfo.GetValue(imageBoxMatcher, null);
            }
            else MessageBox.Show("Some troubles during acqusition pictures from cameras =(");
        }
        private void MatcherForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            AutoAffineMode = false;
            AAHelpPanel.Visible = false;
            AATabControl.TabPages.Clear();
            TestW.pointDataGrid.Rows.Clear();
        }

        
        
        private void ok_btn_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        private void cancel_btn_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void reset_btn_Click(object sender, EventArgs e)
        {
            src.CopyTo(dst,0);
            AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(src, dst, AffineMatrix.Ptr);
            MartixViewUpdate();
            imageBoxMatcher.Image = (Cimage + CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrix)).Bitmap;
                                             //MatcherUtilities.WAffine(BWimage, AffineMatrix);
        }
        private void autoAffine_btn_Click(object sender, EventArgs e)
        {
            initAATabs(10);
            AutoAffineMode = true;
            AAHelpPanel.Visible = true;
        }

        private void initAATabs(int helpTabs)
        {
            System.Collections.ArrayList HelpTabsCollection = new System.Collections.ArrayList(helpTabs);
            for (int i = 0; i < helpTabs; i++)
            {
                //HelpTabs ht;
                //if (i<4) ht = new HelpTabs(
                HelpTabsCollection.Add(new HelpTabs(i, HelpActionTemplate[i%2]));
                AATabControl.TabPages.Add((HelpTabs)HelpTabsCollection[i]);
            }
        }
        
        tets TestW = new tets();
        PropertyInfo pInfo;
        Rectangle imrect;

        private void croprect_btn_Click(object sender, EventArgs e)
        {
            if (drawCropRect) drawCropRect = false;
            else drawCropRect = true;
        }
        private void splitContainer1_Panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (AutoAffineMode)
            {
                if (AATabControl.SelectedIndex % 2 == 0) AASource[AATabControl.SelectedIndex / 2] = e.Location;
                else AADest[AATabControl.SelectedIndex / 2] = e.Location;
                TestW.pointDataGrid.Rows.Add(1);
                TestW.pointDataGrid.Rows[TestW.pointDataGrid.RowCount - 1].SetValues((AATabControl.SelectedIndex % 2 == 0) ? "Source" : "Dest", e.X, e.Y);
                switch (AATabControl.SelectedIndex + 1)
                {
                    case 4:
                        DataGridViewRowCollection data = TestW.pointDataGrid.Rows;

                        double A1 = (Convert.ToDouble(data[2].Cells[2].Value) - Convert.ToDouble(data[0].Cells[2].Value)) / (Convert.ToDouble(data[2].Cells[1].Value) - Convert.ToDouble(data[0].Cells[1].Value));
                        double B1 = Convert.ToDouble(data[0].Cells[2].Value) - Convert.ToDouble(data[0].Cells[1].Value) * A1;

                        double A2 = (Convert.ToDouble(data[3].Cells[2].Value) - Convert.ToDouble(data[1].Cells[2].Value)) / (Convert.ToDouble(data[3].Cells[1].Value) - Convert.ToDouble(data[1].Cells[1].Value));
                        double B2 = Convert.ToDouble(data[3].Cells[2].Value) - Convert.ToDouble(data[1].Cells[1].Value) * A2;

                        double angle = Math.Atan((A2 - A1) / (1 - A1 * A2)) * 180d / Math.PI;
                        AATabControl.SelectedIndex = AATabControl.SelectedIndex + 1;
                        break;
                    case 6:
                        AutoAffineMode = false;
                        AAHelpPanel.Visible = false;
                        AATabControl.TabPages.Clear();



                        AffineMatrix.Ptr = CvInvoke.cvGetAffineTransform(AASource, AADest, AffineMatrix.Ptr);
                        PointF[] ddd = new PointF[3];
                        dst.CopyTo(ddd, 0);
                        for (int i = 0; i < 3; i++)
                        {
                            dst[i].X = ddd[i].X * AffineMatrix[0, 0] + ddd[i].Y * AffineMatrix[0, 1] + AffineMatrix[0, 2];
                            dst[i].Y = ddd[i].X * AffineMatrix[1, 0] + ddd[i].Y * AffineMatrix[1, 1] + AffineMatrix[1, 2];
                        }
                        MartixViewUpdate();
                        imageBoxMatcher.Image = (Cimage + //MatcherUtilities.WAffine(BWimage, AffineMatrix).; //CUDA.CUDAProcessing.AffineTransform(BWimage, AffineMatrix);
                        BWimage.WarpAffine(AffineMatrix, INTER.CV_INTER_NN, WARP.CV_WARP_DEFAULT, new Bgr(Color.White))).Bitmap;
                        break;
                    default:
                        AATabControl.SelectedIndex = AATabControl.SelectedIndex + 1;
                        break;
                }

            }
            else if (drawCropRect)
            {
                CropRectShape.Left = e.X;
                CropRectShape.Top = e.Y;
                CropRectShape.Size = new Size(1, 1);
                if (!CropRectShape.Visible) CropRectShape.Visible = true;
            }


        }
        private void splitContainer1_Panel1_MouseUp(object sender, MouseEventArgs e)
        {
            if (drawCropRect || cropResize)
            {
                if (CropRectShape.Top < imrect.Top) { CropRectShape.Height += CropRectShape.Top - imrect.Top; CropRectShape.Top = imrect.Top; }
                if (CropRectShape.Top > imrect.Bottom) CropRectShape.Top = imrect.Bottom;
                if (CropRectShape.Bottom < imrect.Top) CropRectShape.Height = 0;
                if (CropRectShape.Bottom > imrect.Bottom) CropRectShape.Height = -CropRectShape.Top + imrect.Bottom;

                if (CropRectShape.Left < imrect.Left) { CropRectShape.Width += CropRectShape.Left - imrect.Left; CropRectShape.Left = imrect.Left; }
                if (CropRectShape.Left > imrect.Right) CropRectShape.Left = imrect.Right;
                if (CropRectShape.Right < imrect.Left) CropRectShape.Width = 0;
                if (CropRectShape.Right > imrect.Right) CropRectShape.Width = -CropRectShape.Left + imrect.Right;

                CropRectangle = new Rectangle((int)((CropRectShape.Bounds.Left - (imageBoxMatcher.Width - Cimage.Width / scale) / 2) * scale),
                                                      (int)((CropRectShape.Bounds.Top - (imageBoxMatcher.Height - Cimage.Height / scale) / 2) * scale),
                                                      (int)(CropRectShape.Bounds.Width * scale),
                                                      (int)(CropRectShape.Bounds.Height * scale));

                drawCropRect = false;
                cropResize = false;

                imageBoxMatcher.Invalidate();
                shapeContainer1.Invalidate();
            }
        }
        private void splitContainer1_Panel1_MouseMove(object sender, MouseEventArgs e)
        {
            this.Text = e.Location.ToString();
            int d = 0;
            if (e.Button == System.Windows.Forms.MouseButtons.None && !drawCropRect)
            {
                if (e.X >= CropRectShape.Left - 4 && e.X <= CropRectShape.Left + 4 && e.Y >= CropRectShape.Top && e.Y <= CropRectShape.Bottom) Cursor = Cursors.PanWest;
                if (e.X >= CropRectShape.Right - 4 && e.X <= CropRectShape.Right + 4 && e.Y >= CropRectShape.Top && e.Y <= CropRectShape.Bottom) Cursor = Cursors.PanEast;
                if (e.Y >= CropRectShape.Top - 4 && e.Y <= CropRectShape.Top + 4 && e.X >= CropRectShape.Left && e.X <= CropRectShape.Right) Cursor = Cursors.PanNorth;
                if (e.Y >= CropRectShape.Bottom - 4 && e.Y <= CropRectShape.Bottom + 4 && e.X >= CropRectShape.Left && e.X <= CropRectShape.Right) Cursor = Cursors.PanSouth;
                if (e.Y < CropRectShape.Top || e.Y > CropRectShape.Bottom || e.X < CropRectShape.Left || e.X > CropRectShape.Right) Cursor = Cursors.Default;
                if (e.X <= CropRectShape.Right - 4 && e.X >= CropRectShape.Left + 4 && e.Y <= CropRectShape.Bottom - 4 && e.Y >= CropRectShape.Top + 4) Cursor = Cursors.Default;
            }

            if (e.Button == System.Windows.Forms.MouseButtons.Left && !AutoAffineMode && !drawCropRect)
            {
                if (Cursor == Cursors.PanWest) { d = e.X - CropRectShape.Left; CropRectShape.Left = e.X; CropRectShape.Width -= d; }
                if (Cursor == Cursors.PanEast) { d = e.X - CropRectShape.Right; CropRectShape.Width += d; }
                if (Cursor == Cursors.PanNorth) { d = e.Y - CropRectShape.Top; CropRectShape.Top = e.Y; CropRectShape.Height -= d; }
                if (Cursor == Cursors.PanSouth) { d = e.Y - CropRectShape.Bottom; CropRectShape.Height += d; }
                cropResize = true;
                imageBoxMatcher.Invalidate();
                shapeContainer1.Invalidate();
            }

            if (drawCropRect && e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                imageBoxMatcher.Invalidate();

                int dx = e.X - CropRectShape.Left, dy = e.Y - CropRectShape.Top;
                if (dx < 0)
                {
                    CropRectShape.Left += dx;
                    CropRectShape.Width += Math.Abs(dx);
                }
                else CropRectShape.Width = Math.Abs(dx);
                if (dy < 0)
                {
                    CropRectShape.Top += dy;
                    CropRectShape.Height += Math.Abs(dy);
                }
                else CropRectShape.Height = Math.Abs(dy);
            }
        }

        

    }
    
    class HelpTabs : TabPage
    {
        int NumTab =0;
        Label HelpLabel = new Label();
        public HelpTabs(int numTab, string helptext)
        {
            this.BackColor = Color.Yellow;
            NumTab = numTab+1;
            HelpLabel.Dock = DockStyle.Fill;
            HelpLabel.TextAlign = ContentAlignment.MiddleCenter;
            HelpLabel.Font = new Font("Arial", 14);
            HelpLabel.Text = helptext + (numTab / 2 +1).ToString();
            this.Controls.Add(HelpLabel);
            this.Text = "Действие " + NumTab.ToString();
            
        }
        
    }
}
